<template>
  <div>
    <div style="backgroud:#fff">
      <el-form :inline="true" :model="formInline">
        <el-form-item label="关键字" style="width:30%">
          <el-input
            v-model="searchObj.keyword"
            placeholder="用户名、姓名、手机号码"
          />
        </el-form-item>
        <el-form-item label="创建时间" style="width:50%">
          <el-date-picker
            v-model="dates"
            type="daterange"
            :clearable="false"
            unlink-panels
            range-separator="To"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            :shortcuts="shortcuts"
            size="default"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
      </el-form>

      <el-form-item>
        <el-button type="primary" size="small" @click="initData">
          搜索
        </el-button>
        <el-button size="small" @click="reset">重置</el-button>
      </el-form-item>
      <div>
        <el-button type="success" size="small" @click="handleShowDialog">
          添加
        </el-button>
      </div>
    </div>

    <el-table :data="users" stripe style="width: 100%">
      <el-table-column prop="username" label="用户名" width="100" />
      <el-table-column prop="name" label="姓名" width="100" />
      <el-table-column prop="phone" label="手机" width="150" />
      <el-table-column prop="avatar" label="头像" width="100">
        <template #default="scope">
          <img :src="scope.row.avatar" style="width:50px;height:50px" />
        </template>
      </el-table-column>
      <el-table-column prop="description" label="描述" width="100" />
      <el-table-column prop="status" label="状态" width="100">
        <template #default="scope">
          {{ +scope.row.status === 0 ? '禁用' : '正常' }}
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" width="180" />

      <el-table-column label="操作">
        <template #default="scope">
          <el-button size="small" @click="handleEdit(scope.row)">
            修改
          </el-button>
          <el-button
            size="small"
            type="danger"
            @click="handleDelete(scope.row)"
          >
            删除
          </el-button>
          <el-button
            size="small"
            type="warning"
            @click="showAssignRolesDialog(scope.row)"
          >
            分配角色
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <div style="margin-top:50px">
      <el-pagination
        v-model:current-page="pageNum"
        v-model:page-size="pageSize"
        :page-sizes="[1, 2, 3, 4, 5]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="initData"
        @current-change="initData"
      />
    </div>
    <!-- 分配角色对话框  -->
    <div>
      <el-dialog v-model="dialogAssignRoleVisible" title="分配角色">
        <el-form>
          <el-form-item label="用户名" :label-width="formLabelWidth">
            <el-input v-model="sysUser.username" autocomplete="off" disabled />
          </el-form-item>
          <el-form-item label="角色列表" :label-width="formLabelWidth">
            <el-checkbox-group v-model="checkedRoleIds" size="small">
              <el-checkbox
                v-for="role in roles"
                :key="role.id"
                :label="role.id"
                :checked="role.checked"
              >
                {{ role.roleName }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="dialogAssignRoleVisible = false">取消</el-button>
            <el-button type="primary" @click="handleAssignRoles">
              提交
            </el-button>
          </span>
        </template>
      </el-dialog>
    </div>

    <!-- 新增用户表单对话框 -->
    <div>
      <el-dialog v-model="dialogFormVisible" :title="title">
        <el-form>
          <el-form-item label="用户名" :label-width="formLabelWidth">
            <el-input v-model="sysUser.username" autocomplete="off" />
          </el-form-item>
          <el-form-item
            v-if="!sysUser.id"
            label="密码"
            :label-width="formLabelWidth"
          >
            <el-input v-model="sysUser.password" autocomplete="off" />
          </el-form-item>

          <el-form-item label="用户头像" :label-width="formLabelWidth">
            <el-upload
              class="avatar-uploader"
              :action="uploadUrl"
              :show-file-list="false"
              :headers="headers"
              name="file"
              :on-success="handleAvatarSuccess"
              :on-error="handleAvatarError"
            >
              <img v-if="sysUser.avatar" :src="sysUser.avatar" class="avatar" />
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
          </el-form-item>

          <el-form-item label="姓名" :label-width="formLabelWidth">
            <el-input v-model="sysUser.name" autocomplete="off" />
          </el-form-item>
          <el-form-item label="手机" :label-width="formLabelWidth">
            <el-input v-model="sysUser.phone" autocomplete="off" />
          </el-form-item>
          <el-form-item label="描述" :label-width="formLabelWidth">
            <el-input v-model="sysUser.description" autocomplete="off" />
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取消</el-button>
            <el-button type="primary" @click="handleSaveOrUpdateUser">
              提交
            </el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import {
  GetUsers,
  DeleteUserById,
  SaveUser,
  GetUserById,
  UpdateUser,
  AssignRoles2User,
} from '@/api/sysUser'
import { GetAllRoles } from '@/api/sysRole'
import { useApp } from '@/pinia/modules/app'
import { ElMessage, ElMessageBox } from 'element-plus'
//6、分配角色
const dialogAssignRoleVisible = ref(false)
const checkedRoleIds = ref([])
const roles = ref([])
const showAssignRolesDialog = async row => {
  //先清除缓存：
  checkedRoleIds.value = []
  roles.value = []
  //使用用户id查询 所有角色 和角色他是否已分配
  sysUser.value = row
  const { data } = await GetAllRoles(row.id)
  roles.value = data
  //再对话框中回显  弹出展示
  dialogAssignRoleVisible.value = true
}
//分配角色对话框 提交按钮事件函数
const handleAssignRoles = async () => {
  console.log(checkedRoleIds.value, sysUser.value.id)
  await AssignRoles2User(checkedRoleIds.value, sysUser.value.id)
  ElMessage.success('角色分配成功')
  //关闭对话框
  dialogAssignRoleVisible.value = false
}
//5、上传组件
//上传地址：访问后端上传接口   上传组件访问后端接口时提交请求没有被axios的请求拦截器配置token
const uploadUrl = ref('http://127.0.0.1:8081/admin/system/file/upload/avatar')
const { authorization } = useApp()
//获取localStorage中缓存的token配置请求头
const headers = { token: authorization.token }
//上传成功的回调： 参数1：上传的响应，参数2：本地选中的上传文件
//  响应报文状态码为200时回调
const handleAvatarSuccess = (response, uploadFile) => {
  if (+response.code === 200) {
    //接收上传成功的文件路径赋值给 sysUser的avatar  response代表result对象
    sysUser.value.avatar = response.data
    ElMessage.success('上传成功')
  } else {
    ElMessage.error(response.message)
  }
}
//上传失败的回调
//  响应报文状态码不是200时回调
const handleAvatarError = (error, uploadFile) => {
  // console.log(error)
  ElMessage.error('网络连接失败')
}

const searchObj = ref({})
const dates = ref([])
//分页导航的属性和函数
const pageNum = ref(1)
const pageSize = ref(3)
const total = ref(30)
const users = ref([])
//重置按钮事件函数
const reset = () => {
  pageNum.value = 1
  pageSize.value = 3
  searchObj.value = {}
  //日期选择器回显
  dates.value = []
  initData()
}
//1、角色分页数据查询=======
onMounted(() => {
  //页面初始化时 查询第一页数据渲染展示
  initData()
})
//加载角色分页数据的函数
const initData = async () => {
  // 时间日期选择器 接收到的选中的时间是数组，需要我们手动解析 设置给searchObj提交到后端
  if (dates.value && dates.value.length === 2) {
    //时间日期选中后 我们才解析
    searchObj.value.start = dates.value[0]
    searchObj.value.end = dates.value[1]
  }
  console.log(searchObj.value)
  const { code, message, data } = await GetUsers(
    pageNum.value,
    pageSize.value,
    searchObj.value
  )
  //code值的判断一会提取到 request.js中axios配置的响应拦截器中

  //data代表响应的分页对象
  total.value = data.total
  users.value = data.list
}
//2、删除指定用户
const handleDelete = row => {
  console.log(row)
  ElMessageBox.confirm(`删除用户【${row.username}】，是否确认?`, '删除确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    //确认
    .then(async () => {
      await DeleteUserById(row.id)
      ElMessage({
        type: 'success',
        message: '删除成功',
      })
      //刷新页面数据
      initData()
    })
    //取消
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消删除',
      })
    })
}
//3、新增用户
//新增对话框的属性和函数
const dialogFormVisible = ref(false)
const formLabelWidth = '120px'
const title = ref('新增用户')
const sysUser = ref({})
//打开新增对话框
const handleShowDialog = () => {
  title.value = '新增用户'
  sysUser.value = {}
  dialogFormVisible.value = true
}
//提交新增请求
const handleSaveUser = async () => {
  await SaveUser(sysUser.value)
  ElMessage.success('新增成功')
  //关闭对话框
  dialogFormVisible.value = false
  //刷新页面
  initData()
}
//4、更新用户
//查询回显：弹出对话框
const handleEdit = async row => {
  //查询要更新的角色回显
  // 回显复用新增的对话框，对话框中使用sysRole绑定数据展示
  const { data } = await GetUserById(row.id)
  sysUser.value = data
  title.value = '更新用户'
  dialogFormVisible.value = true
}
//更新方法
const handleUpdateUser = async () => {
  await UpdateUser(sysUser.value)
  dialogFormVisible.value = false
  initData()
}
//提交按钮事件函数：新增和更新都会调用
const handleSaveOrUpdateUser = () => {
  if (sysUser.value.id) {
    //sysRole存在id表示更新
    handleUpdateUser()
  } else {
    //新增
    handleSaveUser()
  }
}
//日期选择器快速选择时  计算时间日期范围的
const shortcuts = [
  {
    text: 'Last week',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    },
  },
  {
    text: 'Last month',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
    },
  },
  {
    text: 'Last 3 months',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
      return [start, end]
    },
  },
]
</script>
<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
